/** 
 * @file	msp_string.h
 * @brief	
 * 
 *  This file implements interfaces declared in file msp_wstring.h.
 * 
 * @author	hlli
 * @version	1.0
 * @date	2010-05-17
 * 
 * @see		
 * 
 * <b>History:</b><br>
 * <table>
 *  <tr> <th>Version	<th>Date		<th>Author	<th>Notes</tr>
 *  <tr> <td>1.0		<td>2010-05-17	<td>hlli	<td>Create this file</tr>
 * </table>
 * 
 */
#ifdef WIN32
#define MSP_WCHAR_SUPPORT
#endif

#if defined _UNICODE || defined MSP_WCHAR_SUPPORT

#include "os.h"
#include "msp_wstring.h"

size_t msp_wcslen( const wchar_t* wstr )
{
	const wchar_t*		sc = wstr;   

	for( ; *sc != L'\0'; ++sc )   
		/* nothing */;

	return sc - wstr; 
}

wchar_t* msp_wcscpy( wchar_t* dest, const wchar_t* src )
{
	wchar_t*	tmp = dest;   

	while(( *dest++ = *src++ ) != L'\0' )   
		/* nothing */;   

	return tmp;   
}

int msp_wcscmp( const wchar_t* cs, const wchar_t* ct )
{
	wchar_t		__res;   

	while(1)
	{   
		if( (__res = *cs - *ct++) != 0 || *cs++ != L'\0' )  /*is !*cs++ necessary? incase more cmp*/
		{
			break;
		}
	}   

	return __res;
}

wchar_t* msp_wcscat( wchar_t* dest, const wchar_t* src )
{
	wchar_t*	tmp = dest;   

	while( *dest )
	{
		dest++;
	}

	while( (*dest++ = *src++) != L'\0' )   
		/* nothing */;

	return tmp;
}

char* msp_wcstombs( const wchar_t* wstr )
{
#if defined(WIN32) || defined(WINCE)
	char*	narrow_str = NULL;
	size_t	count_wstr = 0;
	size_t	bytes_converted = 0;
	int		ret = 0;

	if( NULL == wstr )
	{
		return NULL;
	}

	///malloc buffer to store the corresponding narrow string
	count_wstr = ( msp_wcslen( wstr ) + 1 ) * sizeof( wchar_t );
	narrow_str = (char * )msp_malloc( count_wstr );
	if( NULL == narrow_str )
	{
		return NULL;
	}

	///convert wchar_t-string to char-string
#if defined(WINCE)
	bytes_converted = wcstombs(narrow_str, wstr, count_wstr );
	if( -1 == bytes_converted )
#else
	ret = wcstombs_s(&bytes_converted, narrow_str, count_wstr, wstr, count_wstr );
	if( 0 != ret )
#endif
	{
		free( narrow_str );
		return NULL;
	}
	narrow_str[ bytes_converted ] = '\0';

	return narrow_str;
#else
	return NULL;
#endif
}

wchar_t* msp_mbstowcs( const char* str, size_t str_len )
{
#if defined(WIN32) || defined(WINCE)
	wchar_t*	wstr = NULL;
	int			bytes_required = 0;
	int			bytes_converted = 0;

	///null pointer
	if( NULL == str )
	{
		return NULL;
	}
	
	///calculate size of the buffer required by wchar_t format asr result string
	bytes_required = MultiByteToWideChar( CP_ACP, 0, str, str_len, NULL, 0 );
	if( 0 == bytes_required )
	{
		return NULL;
	}

	///prepare buffer
	wstr = (wchar_t *)malloc( sizeof( wchar_t ) * ( bytes_required + 1 ));
	if( NULL == wstr )
	{
		return NULL;
	}
	wstr[0] = L'\0';

	///convert recognize-result into wchar_t-string
	bytes_converted = MultiByteToWideChar( CP_ACP, 0, str, str_len, wstr, bytes_required );
	wstr[ bytes_converted ] = L'\0';

	return wstr;
#else
	return NULL;
#endif
}
#endif
